/**
 * 算式类单元测试
 * 对Expression类的所有功能进行系统性测试
 * 
 * @author Test Designer
 * @version 1.0
 */
public class ExpressionTest {
    private static int testCount = 0;  // 测试计数器
    private static int passCount = 0;  // 通过计数器
    
    /**
     * 主测试方法
     */
    public static void main(String[] args) {
        System.out.println("===== 算式类（Expression）单元测试 =====\n");
        
        // 测试构造函数
        testConstructor();
        
        // 测试计算功能
        testCalculation();
        
        // 测试格式化输出
        testFormatting();
        
        // 测试getter和setter方法
        testGettersAndSetters();
        
        // 测试有效性检查
        testValidation();
        
        // 测试equals和hashCode方法
        testEqualsAndHashCode();
        
        // 测试边界值情况
        testBoundaryValues();
        
        // 输出测试结果
        System.out.println("\n===== 测试结果统计 =====");
        System.out.println("总测试数: " + testCount);
        System.out.println("通过数: " + passCount);
        System.out.println("失败数: " + (testCount - passCount));
        System.out.println("通过率: " + String.format("%.1f%%", (double)passCount/testCount*100));
        
        if (passCount == testCount) {
            System.out.println("\n🎉 所有测试通过！");
        } else {
            System.out.println("\n❌ 有测试失败，需要检查代码！");
        }
    }
    
    /**
     * 记录测试结果
     */
    private static void recordTestResult(String testName, boolean passed) {
        testCount++;
        if (passed) {
            passCount++;
            System.out.println("✅ 通过: " + testName);
        } else {
            System.out.println("❌ 失败: " + testName);
        }
    }
    
    /**
     * 测试构造函数
     */
    private static void testConstructor() {
        System.out.println("1. 测试构造函数:");
        
        // 测试默认构造函数
        Expression exp1 = new Expression();
        boolean test1 = exp1.getNum1() == 0 && 
                       exp1.getNum2() == 0 && 
                       exp1.getOperator() == '+' && 
                       exp1.getResult() == 0;
        recordTestResult("默认构造函数", test1);
        
        // 测试带参数构造函数 - 加法
        Expression exp2 = new Expression(25, '+', 30);
        boolean test2 = exp2.getNum1() == 25 && 
                       exp2.getOperator() == '+' && 
                       exp2.getNum2() == 30 && 
                       exp2.getResult() == 55;
        recordTestResult("带参数构造函数-加法", test2);
        
        // 测试带参数构造函数 - 减法
        Expression exp3 = new Expression(80, '-', 25);
        boolean test3 = exp3.getNum1() == 80 && 
                       exp3.getOperator() == '-' && 
                       exp3.getNum2() == 25 && 
                       exp3.getResult() == 55;
        recordTestResult("带参数构造函数-减法", test3);
        
        System.out.println();
    }
    
    /**
     * 测试计算功能
     */
    private static void testCalculation() {
        System.out.println("2. 测试计算功能:");
        
        // 测试加法计算
        Expression exp1 = new Expression(50, '+', 30);
        boolean test1 = exp1.getResult() == 80;
        recordTestResult("加法计算：50+30", test1);
        
        // 测试减法计算
        Expression exp2 = new Expression(75, '-', 25);
        boolean test2 = exp2.getResult() == 50;
        recordTestResult("减法计算：75-25", test2);
        
        // 测试负数加法
        Expression exp3 = new Expression(-20, '+', 30);
        boolean test3 = exp3.getResult() == 10;
        recordTestResult("负数加法：-20+30", test3);
        
        // 测试负数减法
        Expression exp4 = new Expression(10, '-', -15);
        boolean test4 = exp4.getResult() == 25;
        recordTestResult("负数减法：10-(-15)", test4);
        
        // 测试大数加法（超过100的中间结果但最终不超过100）
        Expression exp5 = new Expression(60, '+', 35);
        boolean test5 = exp5.getResult() == 95;
        recordTestResult("大数加法：60+35", test5);
        
        System.out.println();
    }
    
    /**
     * 测试格式化输出
     */
    private static void testFormatting() {
        System.out.println("3. 测试格式化输出:");
        
        Expression exp = new Expression(25, '+', 30);
        
        // 测试不包含答案的格式化
        String format1 = exp.formatExpression();
        boolean test1 = format1.equals(" 25 +  30");
        recordTestResult("格式化输出（不含答案）", test1);
        
        // 测试包含答案的格式化
        String format2 = exp.formatWithAnswer();
        boolean test2 = format2.equals(" 25 +  30 =  55");
        recordTestResult("格式化输出（含答案）", test2);
        
        // 测试toString方法
        String toStr = exp.toString();
        boolean test3 = toStr.equals(format2);
        recordTestResult("toString方法", test3);
        
        // 测试负数格式化
        Expression expNeg = new Expression(-15, '-', 8);
        String formatNeg = expNeg.formatWithAnswer();
        boolean test4 = formatNeg.equals("-15 -   8 = -23");
        recordTestResult("负数格式化", test4);
        
        System.out.println();
    }
    
    /**
     * 测试getter和setter方法
     */
    private static void testGettersAndSetters() {
        System.out.println("4. 测试getter和setter方法:");
        
        Expression exp = new Expression();
        
        // 测试setter方法
        exp.setNum1(40);
        exp.setOperator('-');
        exp.setNum2(15);
        
        boolean test1 = exp.getNum1() == 40 && 
                       exp.getOperator() == '-' && 
                       exp.getNum2() == 15 && 
                       exp.getResult() == 25;
        recordTestResult("setter方法功能", test1);
        
        // 测试isAddition和isSubtraction方法
        exp.setOperator('+');
        boolean test2 = exp.isAddition() && !exp.isSubtraction();
        recordTestResult("isAddition和isSubtraction方法", test2);
        
        exp.setOperator('-');
        boolean test3 = exp.isSubtraction() && !exp.isAddition();
        recordTestResult("isSubtraction和!isAddition方法", test3);
        
        System.out.println();
    }
    
    /**
     * 测试有效性检查
     */
    private static void testValidation() {
        System.out.println("5. 测试有效性检查:");
        
        // 测试有效加法（结果≤100）
        Expression exp1 = new Expression(60, '+', 35);
        boolean test1 = exp1.isValid();
        recordTestResult("有效加法：60+35", test1);
        
        // 测试无效加法（结果>100）
        Expression exp2 = new Expression(70, '+', 40);
        boolean test2 = !exp2.isValid();
        recordTestResult("无效加法：70+40", test2);
        
        // 测试有效减法（结果≥0）
        Expression exp3 = new Expression(80, '-', 25);
        boolean test3 = exp3.isValid();
        recordTestResult("有效减法：80-25", test3);
        
        // 测试无效减法（结果<0）
        Expression exp4 = new Expression(25, '-', 70);
        boolean test4 = !exp4.isValid();
        recordTestResult("无效减法：25-70", test4);
        
        // 测试边界值加法（结果=100）
        Expression exp5 = new Expression(60, '+', 40);
        boolean test5 = exp5.isValid();
        recordTestResult("边界值加法：60+40", test5);
        
        // 测试边界值减法（结果=0）
        Expression exp6 = new Expression(50, '-', 50);
        boolean test6 = exp6.isValid();
        recordTestResult("边界值减法：50-50", test6);
        
        System.out.println();
    }
    
    /**
     * 测试equals和hashCode方法
     */
    private static void testEqualsAndHashCode() {
        System.out.println("6. 测试equals和hashCode方法:");
        
        // 测试相同算式
        Expression exp1 = new Expression(25, '+', 30);
        Expression exp2 = new Expression(25, '+', 30);
        boolean test1 = exp1.equals(exp2) && exp1.hashCode() == exp2.hashCode();
        recordTestResult("相同算式equals和hashCode", test1);
        
        // 测试不同算式
        Expression exp3 = new Expression(25, '+', 31);
        boolean test2 = !exp1.equals(exp3);
        recordTestResult("不同算式equals", test2);
        
        // 测试与自身相等
        boolean test3 = exp1.equals(exp1);
        recordTestResult("算式与自身相等", test3);
        
        // 测试与null比较
        boolean test4 = !exp1.equals(null);
        recordTestResult("算式与null比较", test4);
        
        // 测试与不同类型对象比较
        boolean test5 = !exp1.equals("25 + 30");
        recordTestResult("算式与字符串比较", test5);
        
        // 测试不同运算结果但相同运算符的算式
        Expression exp4 = new Expression(30, '+', 25); // 交换操作数位置
        boolean test6 = !exp1.equals(exp4);
        recordTestResult("交换操作数位置的算式", test6);
        
        System.out.println();
    }
    
    /**
     * 测试边界值情况
     */
    private static void testBoundaryValues() {
        System.out.println("7. 测试边界值情况:");
        
        // 测试最小值加法
        Expression exp1 = new Expression(-50, '+', -50);
        boolean test1 = exp1.getResult() == -100;
        recordTestResult("最小值加法：-50+(-50)", test1);
        
        // 测试最大值加法
        Expression exp2 = new Expression(50, '+', 50);
        boolean test2 = exp2.getResult() == 100 && exp2.isValid();
        recordTestResult("最大值加法：50+50", test2);
        
        // 测试包含0的加法
        Expression exp3 = new Expression(0, '+', 0);
        boolean test3 = exp3.getResult() == 0;
        recordTestResult("包含0的加法：0+0", test3);
        
        // 测试包含0的减法
        Expression exp4 = new Expression(0, '-', 0);
        boolean test4 = exp4.getResult() == 0 && exp4.isValid();
        recordTestResult("包含0的减法：0-0", test4);
        
        // 测试大数与负数减法
        Expression exp5 = new Expression(150, '-', -50);
        boolean test5 = exp5.getResult() == 200;
        recordTestResult("大数与负数减法：150-(-50)", test5);
        
        // 测试负数与正数减法
        Expression exp6 = new Expression(-30, '-', 20);
        boolean test6 = exp6.getResult() == -50;
        recordTestResult("负数与正数减法：-30-20", test6);
        
        System.out.println();
    }
}